#ifndef H_OPTIMIZEFULL
#define H_OPTIMIZEFULL
#include "precompiled.h"
#include "optimization.h"
#include "optimizegems.h"
namespace weo
{
    namespace engine
    {
        namespace optimization
        {
            struct Individual
            {
            public:
                weo::engine::item::ItemPtr Items[weo::engine::Slotcount];
                weo::engine::item::EnchantPtr Enchants[weo::engine::Slotcount];
                weo::engine::item::GemPtr Gems[weo::engine::Slotcount*3];
                float Fitness;
                size_t Hash;
                unsigned int Generation;
                void updateHash();
                Individual& operator=(const Individual& indiv);
                bool operator<(const Individual& indiv){return Fitness<indiv.Fitness;}
                friend std::size_t hash_value(const Individual& indiv)
                {
                    return indiv.Hash;
                }
            };
            class OptimizeFull : public Optimization
            {
            private:
                bool Crossover(Individual& child, const Individual& p1, const Individual& p);
                void Selection();
                bool Mutate(Individual& indiv);
                static const int m_MaxPopulation = 32768;
                void evaluateTF(Individual& indiv);
                void Tournamentselection();
                void populateSlot(Individual& indiv, int slot);
                Individual* m_Individuals;
                void OptimizeThreadRunner();
                google::sparse_hash_set<size_t> m_HashSet;
                inline bool Valid(Individual& indiv);
                unsigned int m_Invalidcounter;
            public:
                void Optimize();
                void Output(const Individual& indiv);
                OptimizeFull();
                ~OptimizeFull();
                OptimizeFull(const std::vector<std::vector<const weo::engine::item::Item*>>& value);
            };
        };
    };
};
#endif